const http = require('http');
const https = require('https');
const fs = require('fs');
const { URL } = require('url');

/**
 * 根据url自动判断需要http还是https请求。结果通过Promise返回
 * @param urlString {String} 参数 请求地址
 * @param options {Object} 参数
 * {
 *    method // 方法类型
 *    headers // 请求头
 *    data // 请求体
 *    isBuffer // 设置响应对象的编码指定接收的数据类型，nodejs默认响应数据是Buffer（二进制）。现在设置默认响应文本。需要响应Buffer，如图片，设置isBuffer为true。
 *    timeOut // 设置超时 
 * 
 *    // 相应类型，可选。具体值： DownloadFile=下载文件； base64=返回base64类型数据
 *    responseType 
 *      outputFilePath // 下载文件到本地的路径。 responseType=DownloadFile
 * }
 * @return {Object} 返回值  
 * {
 *    status // 响应状态
 *    headers // 响应头
 *    data // 响应数据
 *    saveFilePath // 保存文件的路径. responseType=DownloadFile
 *    base64Src // base64类型数据. responseType=base64
 * }
 **/
function sendRequest(urlString, options = {}) {
  options.headers = { ...options.headers, 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0' }

  if (!urlString) return;
  const url = new URL(urlString);
  const protocol = url.protocol === 'https:' ? https : http;

  const reqOptions = {
    ...options,
    hostname: url.hostname,
    port: url.port || (url.protocol === 'https:' ? 443 : 80),
    path: url.pathname + url.search,
    method: options.method || 'GET',
    headers: options.headers || {}
  };

  // 处理不同的内容和主体
  if (options.data) {
    let data = options.data;
    if (typeof data === 'object' && !(data instanceof Buffer)) {
      data = JSON.stringify(data);
      reqOptions.headers['Content-Type'] = 'application/json';
    } else if (Buffer.isBuffer(data)) {
      reqOptions.headers['Content-Length'] = data.length;
    } else {
      reqOptions.headers['Content-Length'] = Buffer.byteLength(data);
    }
  }

  return new Promise((resolve, reject) => {
    const req = protocol.request(reqOptions, (res) => {

      let data = [];

      // 通过设置响应对象的编码来指定接收的数据类型。默认情况下，响应数据是以 Buffer（二进制）的形式提供的，可以通过调用 res.setEncoding() 方法来指定你希望以字符串（文本）的形式接收数据。
      if (!options.isBuffer) res.setEncoding('utf8');

      res.on('data', (chunk) => { data.push(chunk); });

      res.on('end', () => {
        // console.log(`=========`, data)
        const responseData = options.isBuffer ? Buffer.concat(data) : data.join('');
        let obj = {
          status: res.statusCode,
          headers: res.headers,
          data: responseData,
        };
        // console.log(`==obj==`, obj)

        // 可选地，处理不同的响应类型
        if (options.responseType === 'DownloadFile') {
          fs.writeFileSync(options.outputFilePath, responseData);
          obj = { ...obj, saveFilePath: options.outputFilePath }
        }
        else if (options.responseType === 'base64') {
          var base64Img = responseData.toString('base64'); //将Buffer对象转换为字符串并以base64编码格式显示
          let content_type = res.headers['content-type'];
          let base64Src = `data:${content_type}` + ';base64,' + base64Img; // 最终可以赋值到img标签中的src属性
          obj = { ...obj, base64Src }
        }
        resolve({ ...obj })
      });
    });

    // 设置请求超时时间为 5000 毫秒（5 秒）
    req.setTimeout(options.timeOut || 1000 * 15, () => { req.abort(); });

    // 处理异常
    req.on('error', (e) => { reject(e) });
    // 写入请求体
    if (options.data) { req.write(options.data); }
    // 发送请求
    req.end();
  })
}
module.exports = sendRequest;